#include "WriterPriorityLock.h"


namespace Zaf {
namespace Sync {



WriterPriorityLock::WriterPriorityLock() {

	m_readerCount = 0;
	m_writerCount = 0;

	m_readerCountLock = CreateSemaphore(nullptr, 1, 1, nullptr);
	m_writerCountLock = CreateSemaphore(nullptr, 1, 1, nullptr);

	m_readLock = CreateSemaphore(nullptr, 1, 1, nullptr);
	m_writeLock = CreateSemaphore(nullptr, 1, 1, nullptr);
}



WriterPriorityLock::~WriterPriorityLock() {

	CloseHandle(m_readerCountLock);
	CloseHandle(m_writerCountLock);

	CloseHandle(m_readLock);
	CloseHandle(m_writeLock);
}



void WriterPriorityLock::ReaderEnter() {

	P(m_readLock);
	P(m_readerCountLock);

	if (m_readerCount == 0) {
		P(m_writeLock);
	}

	++m_readerCount;

	V(m_readerCountLock);
	V(m_readLock);
}



void WriterPriorityLock::ReaderLeave() {

	P(m_readerCountLock);

	--m_readerCount;

	if (m_readerCount == 0) {
		V(m_writeLock);
	}

	V(m_readerCountLock);
}



void WriterPriorityLock::WriterEnter() {

	P(m_writerCountLock);
	
	if (m_writerCount == 0) {
		P(m_readLock);
	}

	++m_writerCount;

	V(m_writerCountLock);

	P(m_writeLock);
}



void WriterPriorityLock::WriterLeave() {

	V(m_writeLock);

	P(m_writerCountLock);

	--m_writerCount;

	if (m_writerCount == 0) {
		V(m_readLock);
	}

	V(m_writerCountLock);
}



}
}